// arg_history.hh
// Written by, Sohail Qayum Malik[sqm@cyberian.pk]

//This is contained type, it should be Assignable and Default Constructible and lot of other things(well it just grew, originally it was not planned as it is now). The constraint checker will check it and spit out lot of horrible horrible compile time errors(if contained type is not as required/rquested)

#include <string>

//Temporary, it should be removed when done
//#include <iostream>

#ifndef	 ARG_HISTORY_HH
#define	 ARG_HISTORY_HH

class arg_history {

   // Temporary, it should be removed when done 
   //public:	

   /* You don't need (argv + index). You've the index and the container has the argv. So mix them up and you'll have the (argv + index). The "const cahr* arg" is just an overkill */ 	   
   const char *arg;	
   int index, appears, cmds;
   size_t pos, cmt_head_pos, cmt_size;
   bool redundency_flag;

   int argc;

   public:

      typedef		arg_history		value_type;
      typedef		arg_history&		reference;
      typedef		arg_history*		pointer;
	  
      bool operator()(void) {
	  
	 return ! ( arg == NULL && cmds == 0 && index == 0  && appears == 0 && pos == 0 && cmt_size == 0 && argc == 0 && redundency_flag == 0 );
      }
      
      bool operator()(const int cmds) {
       
         bool ret = 0;
         
         if ( this->cmds == cmds ) {
         
            if ( this->index > 0 )
             
               ret = 1;  
         }
         
         return ret;
      
         //return ( this->index == index &&  is_not_short() );
      }

      // Should be default contructible
      arg_history(void) : arg(NULL) , cmds(0), index(0), appears(0), pos(0), cmt_head_pos(0), cmt_size(0), argc(0), redundency_flag(0) {
      }

      arg_history(const char *arg, int index, int appears, int cmds, size_t pos, size_t cmt_head_pos, size_t cmt_size, bool redundency_flag = 0, int argc = 0) : arg(arg), cmds(cmds), index(index), appears(appears), pos(pos), cmt_head_pos(cmt_head_pos), cmt_size(cmt_size), argc(argc), redundency_flag(redundency_flag) {
      }
      
      arg_history(const arg_history& ref) {
	 
	 /* If at some stage you decide to use the char *argv[] semantics instead of the index semantics(explained above) then comment the following statement and use the constructor base initialization semantics */     
	 *this = ref;	 
      }

      ~arg_history(void) {
      }

      int get_index(void) {

         return index;	      
      }

      const char *get_arg(void) {

         return arg;	      
      }

      int get_cmds(void) {

         return cmds;	      
      }

      int get_argc(void) {

	 return argc;     
      }	      

      void set_argc(int argc) {

         this->argc = argc;	      
      }

      size_t get_pos(void) {

	 return pos;      
      }

      size_t get_cmt_head_pos(void) {

         return cmt_head_pos;	      
      }

      size_t get_cmt_size(void) {

         return cmt_size;	      
      }

      size_t get_cmd_size(void) {

         return get_cmt_head_pos();	      
      }

      int get_appears(void) {

         return appears;	      
      }

      bool is_short(void) {

         return appears;	      
      }
      
      bool is_not_short(void) {
      
         return !(is_short());
      }

      bool is_not_redundent(void) {

         return !redundency_flag;  	      
      }	      

      arg_history &operator=(int argc) {

         this->argc = argc;

	 return *this;
      } 	      
      	       
      bool operator==(const arg_history& ref) const {

	 return (index == ref.index);      
      }

      bool operator<(const arg_history& ref) const {

	 return (index < ref.index);     
      }
  
      bool operator==(const int cmds) const {

         //bool ret = 0;  	      
/*         
	 //std::cout<<"hoo"<<std::endl;

	 if (this->cmds == cmds) {

            //std::cout<<"1"<<std::endl;

	    if (index > 0) {

              // std::cout<<"2"<<std::endl;		    
               ret = 1;	
            }	       
         }

 	 return ret; */    

         return (this->cmds == cmds && index > 0);	      
      }

      bool operator!=(const int cmds) const {

	 //std::cout<<"yes"<<std::endl;

	 return !(*this == cmds);
      }	      
};
#endif
